package mediatheque.view;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;
import javax.swing.ListSelectionModel;

import tools.DoubleClicEvent;
import tools.DoubleClicListener;



import mediatheque.model.DocumentModel;
import mediatheque.model.EmprunteurModel;
import mediatheque.model.MediathequeModel;
import mediatheque.model.PretModel;

public class GestionPretsView extends JPanel implements Observer{

	private static final long serialVersionUID = 4605634024172220009L;

	private MediathequeModel model;
		
	private JScrollPane scrollTableau;
	private JTable tableauPrets;
	
	private JButton boutonRecherche;
	private JButton boutonReset;	
	private JButton boutonAjout;
	private JButton boutonModification;
	private JButton boutonSuppression;

	private JLabel lblIdentifiant;
	private JLabel lblEmprunteur;
	private JLabel lblDocument;
	private JLabel lblDateEmprunt;
	private JLabel lblDateLimite;

	private JTextField tfIdentifiant;
	private JTextField tfEmprunteur;
	private JTextField tfDocument;
	private JTextField tfDateEmprunt;
	private JTextField tfDateLimite;
	
	private EventListenerList listenerList;

	public GestionPretsView(MediathequeModel model) {
		this.model = model;
		model.addObserver(this);		
		listenerList = new EventListenerList();			
		initialisationComposants();
	}

	protected void initialisationComposants(){
		setPreferredSize(new Dimension(995, 600));

		tableauPrets = new JTable();
		tableauPrets.setRowHeight(25);
		tableauPrets.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				if(e.getValueIsAdjusting())return;			
				boolean afficher = !((ListSelectionModel)e.getSource()).isSelectionEmpty();
				boutonModification.setEnabled(afficher);
				boutonSuppression.setEnabled(afficher);
			}
		});

		scrollTableau = new JScrollPane(tableauPrets);

		Font fontBouton = new Font("Verdana", 0, 12);		
		boutonRecherche = new JButton("Rechercher");
		boutonRecherche.setFont(fontBouton);

		boutonReset = new JButton("Reset");
		boutonReset.setFont(fontBouton);
		boutonReset.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				setListePrets(model.getPrets());
				tfDateLimite.setText("");
				tfDocument.setText("");
				tfIdentifiant.setText("");
				tfEmprunteur.setText("");
				tfDateEmprunt.setText("");				
			}
		});

		boutonAjout = new JButton("Ajouter");
		boutonAjout.setFont(fontBouton);

		boutonModification= new JButton("Modifier");
		boutonModification.setFont(fontBouton);	
		boutonModification.setEnabled(false);

		boutonSuppression = new JButton("Supprimer");
		boutonSuppression.setFont(fontBouton);
		boutonSuppression.setEnabled(false);


		lblIdentifiant = new JLabel("Identifiant : ");
		tfIdentifiant = new JTextField();        
		lblEmprunteur = new JLabel("Emprunteur : ");
		tfEmprunteur = new JTextField();        
		lblDocument = new JLabel("Document : ");
		tfDocument = new JTextField();        
		lblDateEmprunt = new JLabel("Date d'emprunt : ");
		tfDateEmprunt = new JTextField();        
		lblDateLimite = new JLabel("Date limite : ");
		tfDateLimite = new JTextField();


		tableauPrets.setModel(new PretsTableModel(model.getPrets()));
		tableauPrets.getTableHeader().setResizingAllowed(false);
		tableauPrets.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		tableauPrets.setRowSorter(new TableRowSorter<PretsTableModel>((PretsTableModel) tableauPrets.getModel()));
		tableauPrets.getColumnModel().setColumnSelectionAllowed(false);
		tableauPrets.getTableHeader().setReorderingAllowed(false);
		tableauPrets.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				if (e.getClickCount() == 2) {
					int j = tableauPrets.convertRowIndexToModel(tableauPrets.rowAtPoint(e.getPoint()));
					fireMyEvent(new DoubleClicEvent(e.getSource(),(String) tableauPrets.getModel().getValueAt(j, 0)));
				}
			}
		});


		TableColumn colonneIdentifiant = tableauPrets.getColumnModel().getColumn(0);		
		TableColumn colonneEmprunteur = tableauPrets.getColumnModel().getColumn(1);
		TableColumn colonneDocument = tableauPrets.getColumnModel().getColumn(2);
		TableColumn colonneDateEmprunt = tableauPrets.getColumnModel().getColumn(3);
		TableColumn colonneDateLimite = tableauPrets.getColumnModel().getColumn(4);
		TableColumn colonneDateRetour = tableauPrets.getColumnModel().getColumn(5);
		

		// On fixe une largeur pour les colonnes
		colonneIdentifiant.setPreferredWidth(130);
		colonneEmprunteur.setPreferredWidth(200);
		colonneDocument.setPreferredWidth(200);
		colonneDateEmprunt.setPreferredWidth(160);
		colonneDateLimite.setPreferredWidth(160);
		colonneDateRetour.setPreferredWidth(160);
		

		// On centre le texte dans les colonnes
		DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();  
		dtcr.setHorizontalAlignment(SwingConstants.CENTER);
		dtcr.setFont(fontBouton);
		colonneIdentifiant.setCellRenderer(dtcr);
		colonneEmprunteur.setCellRenderer(dtcr);
		colonneDocument.setCellRenderer(dtcr);
		colonneDateEmprunt.setCellRenderer(dtcr);
		colonneDateLimite.setCellRenderer(dtcr);
		colonneDateRetour.setCellRenderer(dtcr);

		placerComposants();

	}
	
	protected void placerComposants() {
		GroupLayout layout = new GroupLayout(this);
		this.setLayout(layout);
		layout.setHorizontalGroup(
			layout.createParallelGroup(GroupLayout.Alignment.LEADING)
			.addGroup(layout.createSequentialGroup()
				.addGap(289, 289, 289)
				.addComponent(boutonAjout)
				.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
				.addComponent(boutonModification)
				.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
				.addComponent(boutonSuppression)
				.addContainerGap(442, Short.MAX_VALUE))
				.addGroup(layout.createSequentialGroup()
				.addGap(38, 38, 38)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(lblEmprunteur)
						.addComponent(lblIdentifiant))
				.addGap(18, 18, 18)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
						.addComponent(tfEmprunteur)
						.addComponent(tfIdentifiant, GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE))
				.addGap(40, 40, 40)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
						.addComponent(lblDocument)
						.addComponent(lblDateEmprunt))
				.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
						.addComponent(tfDateEmprunt)
						.addComponent(tfDocument, GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE))
				.addGap(67, 67, 67)
				.addComponent(lblDateLimite)
				.addGap(18, 18, 18)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addComponent(tfDateLimite, GroupLayout.PREFERRED_SIZE, 150, GroupLayout.PREFERRED_SIZE)
				.addComponent(boutonReset))
				.addGap(346, 346, 346))
				.addComponent(scrollTableau, GroupLayout.DEFAULT_SIZE, 995, Short.MAX_VALUE)
		);
		layout.setVerticalGroup(
			layout.createParallelGroup(GroupLayout.Alignment.LEADING)
			.addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
				.addContainerGap()
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addGroup(layout.createSequentialGroup()
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
				.addComponent(lblIdentifiant)
				.addComponent(tfIdentifiant, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
				.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
				.addComponent(lblEmprunteur)
				.addComponent(tfEmprunteur, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
				.addGroup(layout.createSequentialGroup()
				.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
				.addComponent(lblDocument)
				.addComponent(tfDocument, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
				.addComponent(lblDateLimite)
				.addComponent(tfDateLimite, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
				.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
				.addComponent(lblDateEmprunt)
				.addComponent(tfDateEmprunt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
				.addComponent(boutonReset))))
				.addGap(18, 18, 18)
				.addComponent(scrollTableau, GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE)
				.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
				.addComponent(boutonAjout)
				.addComponent(boutonModification)
				.addComponent(boutonSuppression))
				.addContainerGap())
		);
	}
	
	
	public List<String> getListePretsSelectionne(){
		List<String> listeDocument = new ArrayList<String>();
		int j = 0;
		for (int i = 0; i < tableauPrets.getModel().getRowCount(); i++) {
			j = tableauPrets.convertRowIndexToModel(i);

			if(tableauPrets.getSelectionModel().isSelectedIndex(i)){
				listeDocument.add((String) tableauPrets.getModel().getValueAt(j, 0));
			}			
		}

		return listeDocument;
	}

	void fireMyEvent(DoubleClicEvent evt) {
		Object[] listeners = listenerList.getListenerList();
		for (int i=0; i<listeners.length; i+=2) {
			if (listeners[i]==DoubleClicListener.class) {
				((DoubleClicListener)listeners[i+1]).onDoubleClic(evt);
			}
		}
	}

	public void addRechercherPretsListener(ActionListener al){
		boutonRecherche.addActionListener(al);
	}

	public void addAjouterPretListener(ActionListener al){
		boutonAjout.addActionListener(al);
	}

	public void addSupprimerPretListener(ActionListener al){
		boutonSuppression.addActionListener(al);
	}

	public void addModifierPretListener(ActionListener al) {
		boutonModification.addActionListener(al);
	}

	public void addChangeChampsRechercheListener(DocumentListener dl){
		tfEmprunteur.getDocument().addDocumentListener(dl);
		tfIdentifiant.getDocument().addDocumentListener(dl);
		tfDocument.getDocument().addDocumentListener(dl);
		tfDateEmprunt.getDocument().addDocumentListener(dl);
		tfDateLimite.getDocument().addDocumentListener(dl);		
	}



	public void addDoubleClicListener(DoubleClicListener mel){
		listenerList.add(DoubleClicListener.class, mel);
	}

	public String getValeurIdentifiant(){
		return tfIdentifiant.getText();
	}

	public String getValeurEmprunteur(){
		return tfEmprunteur.getText();
	}

	public String getValeurDocument(){
		return tfDocument.getText();
	}
	public String getValeurDateEmprunt(){
		return tfDateEmprunt.getText();
	}

	public String getValeurDateLimite(){
		return tfDateLimite.getText();
	}

	public void setListePrets(Collection<PretModel> collection){
		((PretsTableModel)tableauPrets.getModel()).setData(collection);
	}

	class PretsTableModel extends AbstractTableModel{

		private static final long serialVersionUID = 1L;

		private String[] columnNames = {"Identifiant", "Emprunteur", "Document", "Date d'emprunt", "Date limite", "Date retour"};

		private List<PretModel> listePrets;

		public PretsTableModel(Collection<PretModel> listeEmprunteurs) {
			setData(listeEmprunteurs);
		}

		public void setData(Collection<PretModel> listeEmprunteurs){
			this.listePrets = new ArrayList<PretModel>(listeEmprunteurs);	
			fireTableDataChanged();
		}

		@Override
		public int getColumnCount() {
			return columnNames.length;
		}

		@Override
		public int getRowCount() {
			return listePrets.size();
		}

		@Override
		public String getColumnName(int column) {
			return columnNames[column];
		}

		@Override
		public Object getValueAt(int row, int col) {
			switch(col){
			case 0:
				return listePrets.get(row).getIdentifiant();
			case 1:
				//return listePrets.get(row).getIdentifiantEmprunteur();
				EmprunteurModel emp = model.getEmprunteur(listePrets.get(row).getIdentifiantEmprunteur());
				return emp.getNom()+" "+emp.getPrenom();
			case 2:
				//return listePrets.get(row).getIdentifiantDocument();
				DocumentModel doc = model.getDocument(listePrets.get(row).getIdentifiantDocument());
				if(doc != null) return doc.getNom();
				else return listePrets.get(row).getIdentifiantDocument();
			case 3 : 
				return listePrets.get(row).getDateEmprunt();
			case 4 : 
				return listePrets.get(row).getDateRetourLimite();
			case 5 : 
				if(!listePrets.get(row).getDateRetourEffectif().equals("")){					
					return listePrets.get(row).getDateRetourEffectif();
				}else{
					Calendar c1 = Calendar.getInstance();
					Calendar c2 = Calendar.getInstance();					
					
					SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
					try {
						c1.setTime(format.parse(listePrets.get(row).getDateRetourLimite()));
						long diffDays = (c2.getTimeInMillis() - c1.getTimeInMillis()) / (24 * 60 * 60 * 1000);
						if(diffDays > 1){
							return "Retard "+diffDays+" jours";	
							
						}else if(diffDays > 0){
							return "Retard "+diffDays+" jour";	
						}
					} catch (ParseException e) {
						e.printStackTrace();
					}
					return "";	
				}
				
			default: 
				return listePrets.get(row).getIdentifiant();	
			}
		}

	}

	@Override
	public void update(Observable o, Object arg) {
		if((Integer)arg == MediathequeModel.PRET){
			setListePrets(model.getPrets());
		}
	}
}
